import * as fs from "fs";
import { Controller, Get, Module, Response } from "@nestjs/common";
import { FastifyReply } from "fastify";
import { ArticleService } from "src/article/article.service";

import { PrismaClient } from "@prisma/client";
import configuration from "src/common/configuration";
import { ArticleContentDataType } from "src/article/enum/article-content-data";
import { ArticleModule } from "src/article/article.module";

const pageSize = 10;
const RSSFilePath = configuration.resource.RSSFilePath;

@Controller("rss")
class RSS {
  constructor(
    private readonly prisma: PrismaClient,
    private readonly articleService: ArticleService,
  ) {
    if (configuration.rss?.enable) this.run();
    else {
      if (fs.existsSync(RSSFilePath)) {
        fs.rmSync(RSSFilePath);
      }
    }
  }

  @Get("/")
  getRSSFile(@Response() response: FastifyReply) {
    if (!fs.existsSync(RSSFilePath)) response.status(404).send("内容不存在");
    try {
      const rss = fs.readFileSync(RSSFilePath, "utf-8");
      response.header("Content-Type", "text/xml;charset=utf-8");
      response.send(rss);
    } catch (e) {
      console.error(e);
      response.status(500).send("内部错误");
    }
  }

  async makeRSSFile() {
    const websiteSetupYear = new Date(
      configuration.website.setUpTime,
    ).getFullYear();
    const nowYear = new Date().getFullYear();

    const managingEditor = (() => {
      if (
        configuration.user?.master?.nickname &&
        configuration.user?.master?.emails &&
        configuration.user?.master?.emails[0]
      ) {
        return `${configuration.user.master.emails[0]} (${configuration.user.master.nickname})`;
      }
      return "hongweifei@cyue.net (Weifei)";
    })();

    let content = `<?xml version="1.0" encoding="UTF-8" ?>`;
    content += `
      <rss version="2.0"
        xmlns:atom="http://www.w3.org/2005/Atom"
        xmlns:content="http://purl.org/rss/1.0/modules/content/"
        xmlns:dc="http://purl.org/dc/elements/1.1/"
        xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
      >
      <channel>
        <atom:link href="${configuration.website.url}/rss" rel="self" type="application/rss+xml" />
        <title>${configuration.website.name}</title>
        <link>${configuration.website.url}</link>
        <description>${configuration.website.description}</description>
        <language>zh-CN</language>
        <lastBuildDate>${new Date().toUTCString()}</lastBuildDate>
        <copyright>Copyright ${websiteSetupYear}-${nowYear} ${configuration.website.copyright} All Rights Reserved</copyright>
        <managingEditor>${managingEditor}</managingEditor>
    `;

    const result = await this.prisma.article_sort.findMany();
    for (let index = 0; index < result.length; index++) {
      const element = result[index];

      const articleResult = await this.prisma.article.findMany({
        select: {
          id: true,
        },
        orderBy: {
          update_time: "desc",
        },
        where: {
          sort_id: element.id,
        },
        take: pageSize,
      });
      const articleIDs = new Array(articleResult.length);
      for (let j = 0; j < articleResult.length; j++) {
        articleIDs[j] = articleResult[j].id;
      }

      const articleArray = await this.articleService.getArticleArrayByIDs(
        articleIDs,
        {
          getRichContent: true,
          contentType: ArticleContentDataType.HTML,
        },
      );
      if (!articleArray) continue;
      if (articleArray)
        for (let j = 0; j < articleArray.length; j++) {
          const article = articleArray[j];

          // 处理资源文件路径
          const contentData = article.content;
          let contentHTML = "";
          if (contentData.content) {
            contentHTML = contentData.content.replace(
              /src="(\/resource\/[^"]*)"/gi,
              `src="${configuration.website.url}$1"`,
            );
          }

          const date = new Date(article.update_time).toUTCString();
          content += `
            <item>
                <title>${element.name}——${article.title}</title>
                <link>${configuration.website.url}/pages/article/${article.id}</link>
                <category>${element.name}</category>
                <guid>${configuration.website.url}/pages/article/${article.id}</guid>
                <pubDate>${date}</pubDate>
                <description><![CDATA[${article.author}——${article.title}]]></description>
                <dc:creator><![CDATA[${article.author}]]></dc:creator>
                <content:encoded><![CDATA[${contentHTML}]]></content:encoded>
            </item>
          `;
        }
    }

    content += `
      </channel>
    `;
    content += `</rss>`;

    fs.writeFileSync(RSSFilePath, content, "utf-8");
  }

  run() {
    if (!configuration.rss) {
      return;
    }
    try {
      this.makeRSSFile();
    } catch (e) {
      console.error(e);
    }
    // 配置可能发生改变
    const fileUpdateInterval = configuration.rss.updateInterval * 1000 * 60;
    setTimeout(this.run, fileUpdateInterval);
  }
}
@Module({
  imports: [ArticleModule],
  controllers: [RSS],
})
export class RSSModule {}
